﻿using MediatR;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.EntityFrameworkCore;
using System.Collections;
using System.ComponentModel.Design;
using T.Materials.API.Application.Command.MaterialRequisitionCommand;
using T.Materials.Domain.Dto;
using T.Materials.Domain.Model;
using T.Materials.Repository;
using T.Materials.Repository.MaterialsInterface;
using static T.Materials.Domain.Enum.Enums;

namespace T.Materials.API.Application.CommandHandler.MaterialRequisitionCommandHandler
{
    /// <summary>
    /// 更新物资领用命令处理器
    /// </summary>
    public class UpdateMaterialRequisitionCommandHandler : IRequestHandler<UpdateMaterialRequisitionCommand, int>
    {
        /// <summary>
        /// 物资领用仓储接口
        /// </summary>
        protected readonly IMaterialRequisitionRepository materialRequisitionRepository;

        /// <summary>
        /// 上下文
        /// </summary>
        protected readonly MEFDbContext mEFDbContext;

        /// <summary>
        /// 物资仓库接口
        /// </summary>
        protected readonly IMaterialStoreRepository materialStoreRepository;

        /// <summary>
        /// 存储物资领用存储仓储接口
        /// </summary>
        protected readonly IStorageMaterialsRepository storageMaterialsRepository;

        /// <summary>
        /// 映射器
        /// </summary>
        //protected readonly IMapper mapper;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="storageMaterialsRepository">存储物资领用存储仓储接口</param>
        /// <param name="materialRequisitionRepository">物资领用仓储接口</param>
        /// <param name="mEFDbContext">上下文</param>
        /// <param name="materialStoreRepository">物资仓库接口</param>
        /// <param name="mapper">映射器</param>
        public UpdateMaterialRequisitionCommandHandler(IMaterialRequisitionRepository materialRequisitionRepository, MEFDbContext mEFDbContext, IMaterialStoreRepository materialStoreRepository, IStorageMaterialsRepository storageMaterialsRepository)
        {
            this.materialRequisitionRepository = materialRequisitionRepository;
            this.mEFDbContext = mEFDbContext;
            this.materialStoreRepository = materialStoreRepository;
            //this.mapper = mapper;
            this.storageMaterialsRepository = storageMaterialsRepository;
        }

        /// <summary>
        /// 处理更新物资领用命令
        /// </summary>
        /// <param name="request">更新物资领用命令</param>
        /// <param name="cancellationToken">取消标记</param>
        /// <returns>返回受影响的行数</returns>
        public async Task<int> Handle(UpdateMaterialRequisitionCommand request, CancellationToken cancellationToken)
        {
            var strategy = mEFDbContext.Database.CreateExecutionStrategy();

            return await strategy.ExecuteAsync(async () =>
            {
                using (var transaction = mEFDbContext.Database.BeginTransaction())
                {
                    try
                    {
                        // 更新领用信息
                        var res = await materialRequisitionRepository.GetModelAsync(request.MaterialRequisitionId);
                        await materialRequisitionRepository.UpdateAsync(res);

                        // 准备一个字典来存储 MaterialStoreId 和原先领用的数量
                        var originalQuantities = new Dictionary<int, int>();

                        // 获取当前领用明细中所有 MaterialStoreId 对应的原先领用数量
                        var existingRequisitions = await storageMaterialsRepository.GetAsync(x => x.MaterialRequisitionId == request.MaterialRequisitionId);
                        foreach (var existing in existingRequisitions)
                        {
                            if (!originalQuantities.ContainsKey(existing.MaterialStoreId))
                            {
                                originalQuantities[existing.MaterialStoreId] = existing.QuantityReceived;
                            }
                        }

                        // 循环领用明细 ID，更新库存和领用明细
                        foreach (var item in request.materialRequisitionDtos)
                        {
                            // 获取库存信息
                            var materialStore = await materialStoreRepository.GetModelAsync(item.MaterialStoreId);

                            // 如果该物资之前被领用过，则将其数量加回到库存中
                            if (originalQuantities.ContainsKey(item.MaterialStoreId))
                            {
                                materialStore.Number += originalQuantities[item.MaterialStoreId];
                            }

                            // 更新库存数量（减去当前领用的数量）
                            materialStore.Number -= item.QuantityReceived;

                            // 更新库存
                            await materialStoreRepository.UpdateAsync(materialStore);

                            // 更新领用明细表
                            var storageMaterial = new StorageMaterials() // 假设需要创建一个新的实体或更新现有实体
                            {
                                MaterialRequisitionId = request.MaterialRequisitionId,
                                MaterialStoreId = item.MaterialStoreId,
                                QuantityReceived = item.QuantityReceived,
                                UpdatedBy = request.UpdatedBy,
                                UpdatedDate = DateTime.Now
                            };

                            // 检查是否已存在该记录的领用明细，如果存在则更新，否则添加新记录
                            var existingStorageMaterial = existingRequisitions.FirstOrDefault(x => x.MaterialStoreId == item.MaterialStoreId);
                            if (existingStorageMaterial != null)
                            {
                                // 更新现有记录
                                existingStorageMaterial.QuantityReceived = item.QuantityReceived;
                                existingStorageMaterial.UpdatedBy = request.UpdatedBy;
                                existingStorageMaterial.UpdatedDate = DateTime.Now;
                                await storageMaterialsRepository.UpdateAsync(existingStorageMaterial);
                            }
                            else
                            {
                                // 添加新记录
                                await storageMaterialsRepository.AddAsync(storageMaterial);
                            }
                        }
                        // 提交事务
                        transaction.Commit();
                        return 1;
                    }
                    catch (Exception)
                    {
                        // 回滚事务
                        transaction.Rollback();

                        throw;
                    }
                }
            });
        }
    }
}

////循环领用明细ID 将原先的领用明细内存储的数量更新
//foreach (var item in request.materialRequisitionDtos)
//{
//    //拿到原先表中存储的数量
//    var getStart = await materialStoreRepository.GetModelAsync(item.MaterialStoreId);

//    var getInfo = await storageMaterialsRepository.GetAsync(x => x.MaterialStoreId == item.MaterialStoreId);
//    //拿到明细表的主键ID
//    var getId = getInfo.FirstOrDefault().StorageMaterialsId;

//    //拿到领用明细表中领用数量
//    var getEnd = await storageMaterialsRepository.GetModelAsync(getId);
//    //更新原先表中的领用数量
//    getStart.Number += getEnd.QuantityReceived;

//    ////更新当前明细表中的领用数量
//    //getEnd.QuantityReceived -= item.QuantityReceived;

//    //更新数据
//    await materialStoreRepository.UpdateAsync(getStart);
//    //await storageMaterialsRepository.UpdateAsync(getEnd);
//}

//// 循环领用明细ID 将领用明细内存储的数量更新
//foreach (var item in request.materialRequisitionDtos)
//{
//    //拿到原先表中存储的数量
//    var getStart = await materialStoreRepository.GetModelAsync(item.MaterialStoreId);
//    //更新原先表中的领用数量
//    getStart.Number -= item.QuantityReceived;
//    var store = await storageMaterialsRepository.GetModelAsync(request.MaterialRequisitionId);
//    //将新的领用数量存入领用明细表
//    store.QuantityReceived = item.QuantityReceived;
//    store.UpdatedBy = request.UpdatedBy;
//    store.UpdatedDate = DateTime.Now;
//    await storageMaterialsRepository.UpdateAsync(store);
//}
